package com.tongji.diy.model.furniturePlacementOptimization
{
	import com.tongji.diy.event.TestShowLayOutEvent;
	import com.tongji.diy.event.furnitureOptimizationEvent.IterationTestEvent;
	import com.tongji.diy.model.DoorsAndWindows;
	import com.tongji.diy.model.NoAccessAssignment;
	import com.tongji.diy.model.RoomDataModel;
	import com.tongji.diy.model.furniturePlacementOptimization.assembleComplement.FurnitureBase;
	import com.tongji.diy.model.furniturePlacementOptimization.assembleComplement.NoAccessibleFurniture;
	import com.tongji.diy.utils.PolygonMath;
	
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.utils.getTimer;
	
	import org.robotlegs.mvcs.Actor;
	
	public class IntegrateModel extends Actor
	{
		[Inject]
		public var roomModel:RoomDataModel;
		[Inject]
		public var assembleModel:AssembleModel;
		[Inject]
		public var doorAndWindowModel:DoorsAndWindows
		
		private var _noAccessFurniture:Vector.<NoAccessibleFurniture>;
		private var _blockLayouts:Vector.<BlockLayoutConstructor> = new Vector.<BlockLayoutConstructor>;
		//门窗包围盒
		private var doorAndWindowBoxes:Vector.< Vector.<Point> > = new Vector.< Vector.<Point> > ;
		
		
		public static var stopSign:Boolean = false;
		
		public function IntegrateModel()
		{
			super();
		}
		
		//由assmbleModel通知该model接管工作
		public function getStart():void
		{
			trace("timeStartAssignment",getTimer());
			doorAndWindowModel.refreshinfo();	
			buildDoorAndWindowBoundingBox();
			var blocks:Vector.<Vector.<FurnitureBase>> = assembleModel.blocks;
			_noAccessFurniture = assembleModel.noAccessFurniture;
			for(var i:int = 0; i < blocks.length; ++i)
			{
				_blockLayouts.push(new BlockLayoutConstructor());
				_blockLayouts[i].init(roomModel.rooms[0],blocks[i]);
			}
			main();
			trace("timeFinishAssignment",getTimer());
		}
		
		private function main():void
		{
			//将每个furnitureBlock进行摆放
			while(furnitureBlockCollision()||doorAndWindowCollision())
			{
				for(var i:int = 0; i < _blockLayouts.length; ++i)
				{			
					_blockLayouts[i].reConstruct();
				}
			}
			//处理每个部分的nearby	
			for(i = 0; i < _blockLayouts.length; ++i)
			{
				_blockLayouts[i].assignNearby();
				
				if(OptimizationParameter.DEBUG)
					dispatch(new IterationTestEvent(IterationTestEvent.TEST,
						_blockLayouts[i].data.perFrameData.nearbylist,
						_blockLayouts[i].data.perFrameData.recorder, 
						_blockLayouts[i].facalBlock,
						_blockLayouts[i].data._beddingList, 
						_blockLayouts[i].data._seatList ));
			}
			
			
			if(!OptimizationParameter.DEBUG)
			{
				//暂时取消，最后要回恢复
				while(blockCollision()|| doorAndWindowCollision())
				{
					for(i = 0; i < _blockLayouts.length; ++i)
						_blockLayouts[i].assignNearby();
				}
				
				//将结果显示出来
	     		for(i = 0; i < _blockLayouts.length; ++i)
					showLayout(_blockLayouts[i]);
			}
			
			//noaccessiblefurniture Handle
			if(_noAccessFurniture && _noAccessFurniture.length)
			{
				var noAccAssign:NoAccessAssignment = new NoAccessAssignment(_blockLayouts,_noAccessFurniture);
			}
			showNoAccessibleFurniture(_noAccessFurniture);
		}
		
		public function sceneCallBackHandler():void
		{
			for(var i:int = 0; i < _blockLayouts.length; ++i)
			{
				_blockLayouts[i].assignNearby();
				dispatch(new IterationTestEvent(IterationTestEvent.TEST,
					_blockLayouts[i].data.perFrameData.nearbylist,
					_blockLayouts[i].data.perFrameData.recorder,
					_blockLayouts[i].facalBlock,
					_blockLayouts[i].data._beddingList,
					_blockLayouts[i].data._seatList ));
			}
		}
		
		private function showLayout(block:BlockLayoutConstructor):void
		{
			dispatch(new TestShowLayOutEvent(TestShowLayOutEvent.SHOW_LAYOUT, block.showList))
		}
		
		private function showNoAccessibleFurniture(noAccessFurniture:Vector.<NoAccessibleFurniture>):void
		{
			var v:Vector.<FurnitureBase> = new Vector.<FurnitureBase>;
			for(var i:int = 0; i < noAccessFurniture.length; ++i)
				v.push(noAccessFurniture[i]);
			dispatch(new TestShowLayOutEvent(TestShowLayOutEvent.SHOW_LAYOUT, v))
		}

		private function doorAndWindowCollision():Boolean
		{
			for(var i:int = 0; i < _blockLayouts.length; ++i)
			{
				for(var k:int = 0; k < _blockLayouts[i].boundingBoxes.length; ++k)
				{
					for(var j:int = 0; j < doorAndWindowBoxes.length; ++j)
					{
						if(PolygonMath.rectangleSeparatingAxisCollisionTest(_blockLayouts[i].boundingBoxes[k], doorAndWindowBoxes[j]) == -1)
						{
							return true;
						}
					}
				}
			}
			return false;
		}
		
		private function buildDoorAndWindowBoundingBox():void
		{
			for(var i:int; i < doorAndWindowModel.doors.length; ++i)
			{
				var pos:Point = doorAndWindowModel.doors[i].globalpos.subtract(new Point(roomModel.rooms[0].x, roomModel.rooms[0].y));
				var angle:Number = doorAndWindowModel.doors[i].globalangle*Math.PI/180 - Math.PI/2;
				var width:Number = doorAndWindowModel.getwidth();
				var accessDistance:Number = OptimizationParameter.DOOR_WINDOW_DISTANCE;
				var AABB:Vector.<Point> = new Vector.<Point>;
				var leftTop:Point = new Point(pos.x - width/2, pos.y);
				AABB.push(leftTop);
				var rightTop:Point = new Point(pos.x + width/2, pos.y);
				AABB.push(rightTop);
				var rightBottom:Point = new Point(pos.x + width/2, pos.y - accessDistance);
				AABB.push(rightBottom);
				var leftBottom:Point = new Point(pos.x - width/2, pos.y  - accessDistance);
				AABB.push(leftBottom);
				
				var moveM1:Matrix = new Matrix();
				moveM1.translate(-pos.x, -pos.y);
				var moveM2:Matrix = new Matrix();
				moveM2.translate(pos.x, pos.y);
				var rotateM:Matrix = new Matrix();
				rotateM.rotate(-angle);
				moveM1.concat(rotateM);
				moveM1.concat(moveM2);
				var transM:Matrix = moveM1;
				for(var j:int = 0;j<AABB.length;j++)
				{
					AABB[j] = transM.transformPoint(AABB[j]);
				}
				doorAndWindowBoxes.push(AABB);
			}			
		}
		
		//判断furnitureblock间的碰撞情况，返回false说明无碰撞
		private function furnitureBlockCollision():Boolean
		{			
			for(var i:int = 0; i < _blockLayouts.length; ++i)
			{
				for(var j:int = i+1; j < _blockLayouts.length; ++j)
				{
					if(PolygonMath.rectangleSeparatingAxisCollisionTest(_blockLayouts[i].furnitureBlock, _blockLayouts[j].furnitureBlock) == -1)
					{
						return true;
					}	
				}
			}
			return false;
		}
		//处理所有包围盒的碰撞问题
		private function blockCollision():Boolean
		{
			for(var i:int = 0; i < _blockLayouts.length; ++i)
			{
				for(var j:int = i+1; j < _blockLayouts.length; ++j)
				{
					for(var u:int = 0; u < _blockLayouts[i].boundingBoxes.length; ++u)
					{
						for(var v:int = 0; v  < _blockLayouts[j].boundingBoxes.length; ++v)
						{
							if(PolygonMath.rectangleSeparatingAxisCollisionTest(_blockLayouts[i].boundingBoxes[u], _blockLayouts[j].boundingBoxes[v]) == -1)
							{
								return true;
							}	
						}
					}
					
				}
			}
			return false;
		}
		
	}
}